package models

import (
	"ginstudydemo.com/main/dao"
	"sort"
)

type ICategoryModel interface {
	CreateTestDataHandler()
}

type CategoryModel struct{}

func NewCategoryModel() *CategoryModel {
	return &CategoryModel{}
}

func (u CategoryModel) GetCategoryAndResRecursionData(query CateAndResUseRecursionParams) ([]CategoryAndResRecursionData, error) {
	var flatCategories []CategoryAndResRecursionData
	var err error

	if query.IsSubCate {
		if query.CategoryCode != "" {
			err = dao.Db.Debug().Raw(`
                WITH RECURSIVE cte AS (
                    SELECT * FROM content_type WHERE code = ? AND is_deleted = 0
                    UNION ALL
                    SELECT c.* FROM content_type c
                    INNER JOIN cte ON c.parent_id = cte.id
                )
                SELECT * FROM cte WHERE is_deleted = 0;
            `, query.CategoryCode).Scan(&flatCategories).Error
		} else {
			err = dao.Db.Debug().Raw(`
                WITH RECURSIVE cte AS (
                    SELECT * FROM content_type WHERE parent_id IS NULL AND is_deleted = 0
                    UNION ALL
                    SELECT c.* FROM content_type c
                    INNER JOIN cte ON c.parent_id = cte.id
                )
                SELECT * FROM cte WHERE is_deleted = 0;
            `).Scan(&flatCategories).Error
		}
	} else {
		if query.CategoryCode != "" {
			err = dao.Db.Debug().Table("content_type").
				Where("code = ? AND is_deleted = 0", query.CategoryCode).
				Find(&flatCategories).Error
		} else {
			err = dao.Db.Debug().Table("content_type").
				Where("is_deleted = 0").
				Find(&flatCategories).Error
		}
	}

	if err != nil {
		return nil, err
	}

	resultCategories := flatCategories

	if query.IsResource {
		var categoryIDs []int64
		for _, cat := range resultCategories {
			categoryIDs = append(categoryIDs, cat.ID)
		}

		var resources []ResourceRes
		err = dao.Db.Debug().Table("resource").
			Where("category_id IN ? AND is_deleted = 0", categoryIDs).
			Find(&resources).Error
		if err != nil {
			return nil, err
		}

		resourceMap := make(map[int64][]ResourceRes)
		for _, r := range resources {
			resourceMap[int64(r.CategoryID)] = append(resourceMap[int64(r.CategoryID)], r)
		}

		for i, cat := range resultCategories {
			resultCategories[i].ResourceData = resourceMap[cat.ID]
		}
	}

	if query.RecursiveDisplay {
		return buildCategoryTree(resultCategories), nil
	}

	return resultCategories, nil
}

// 修复版树形构建函数
func buildCategoryTree(flat []CategoryAndResRecursionData) []CategoryAndResRecursionData {
	nodeMap := make(map[int64]*CategoryAndResRecursionData)

	// 第一次遍历：使用原始数据的指针
	for i := range flat {
		nodeMap[flat[i].ID] = &flat[i]
	}

	// 第二次遍历：构建父子关系
	var roots []*CategoryAndResRecursionData
	for i := range flat {
		node := &flat[i]

		if node.ParentID != 0 {
			if parent, exist := nodeMap[node.ParentID]; exist {
				// 直接修改原始数据的Children字段
				parent.Children = append(parent.Children, *node)
			}
		} else {
			roots = append(roots, node)
		}
	}

	// 排序根节点
	sort.Slice(roots, func(i, j int) bool {
		return roots[i].SortOrder < roots[j].SortOrder
	})

	// 转换为值类型
	result := make([]CategoryAndResRecursionData, len(roots))
	for i, root := range roots {
		result[i] = *root
	}

	return result
}
